<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			function Element(name,attr,child){
				this.name = name;
				this.attr = attr;
				this.child = child;
			}
			
			
			function createElement(name,attr,child){
				return new Element(name,attr,child)
			}
			
			var dom1 = createElement('ul',{class:'dd'},[
				createElement('li',{class:'ffdxx'},['ff']),
				createElement('li',{class:'ffd'},['ff2']),
				createElement('li',{class:'ffd'},['ff3'])
				])
			var dom2 = createElement('div',{class:'dsd',id:'ddd'},[
					createElement('li',{class:'ff'},['ff']),
					createElement('li',{class:'ffd'},['ff2']),
					createElement('div',{class:'ffd'},['ff5'])
					])
			var ATTR = 'ATTR'
			var REPLACE = 'REPLACE'
			var REMOVE = 'REMOVE'
			var TEXT = 'TEXT'		
					
		     function diff(oldnode,newold){
				 var patchs = {};
				 var index = 0;
				 walk(oldnode,newold,patchs,index)
				 return patchs
			 }
			 var mindex = 0
			 function walk(oldnode,newold,patchs,index){
				 var mpatchs = []
				 if(!newold){
									 mpatchs.push({
										 type:REMOVE,
										 index:index
									 })
				}else if(typeof oldnode=='string'&&typeof newold=='string'){
					 if(oldnode!=newold){
						 mpatchs.push({
							 type:TEXT,
							 text:newold
						 })
					 }
				 }else if(oldnode.name==newold.name){
					 var sattr = {}
					 for(var i in oldnode.attr){
						 if(oldnode.attr[i]!=newold.attr[i]){
							 sattr[i] = newold.attr[i]
						 }
					 }
					 for(var j in newold.attr){
						 if(oldnode.attr[j]!=newold.attr[j]){
						 	 sattr[j] = newold.attr[j] 
						 }
					 }
					 if(Object.keys(sattr).length>0){
						  mpatchs.push({
														 type:ATTR,
														 attr:sattr
					 })
					 }
					 console.log(oldnode)
					 oldnode.child.forEach(function(val,indexx){
						 walk(val,newold.child[indexx],patchs,++mindex)
					 })
					
				 }else{
					 mpatchs.push({
						 type:REPLACE,
						 node:newold
					 })
				 }
				 
				 
				    if(mpatchs.length>0){
						 patchs[index] = mpatchs
					}
					
				 
				 
			 }
			  var windex = 0;
			 function dopatchs(patchs,el){
				
				 pwalk(patchs,el)
			 }
			 
			 function pwalk(patchs,node){
				 var currentP = patchs[windex]
				 if(currentP){
					  currentP.forEach(function(val,index){
						  console.log(val)
					    switch(val.type){
							case TEXT:
							node.textContent = val.text
							break;
							case ATTR:
							for(var i in val.attr){
								node.setAttribute(i,val.attr[i])
							}
							break;
							case REPLACE:
							var d
							if(val.node instanceof Element){
								d = render(val.node)
							}else{
								d = document.createTextNode(val.node)
							}
							console.log(d)
							node.parentNode.replaceChild(d,node)
							break
							case REMOVE:
							node.parentNode.removeChild(node)
							break
							
						}
				 })
				 }
				
				 node.childNodes.forEach(function(val,index){
					 windex++
					 pwalk(patchs,val)
				 })
			 }
			 
			 
			 
			 
				
			
			function render(node){
				var name = document.createElement(node.name)
				for(var i in node.attr){
					name.setAttribute(i,node.attr[i])
				}
				node.child.forEach(function(val,index){
					if(val instanceof Element){
						name.appendChild(render(val)) 
					}else{
						name.appendChild(document.createTextNode(val))
					}
				})
				
				return name
			}
			
			function domRender(dom,el){
				el.appendChild(dom)
			}
			
			var zsdom = render(dom1)
			console.log(dom1)
			domRender(zsdom,document.body)
			var patchs = diff(dom1,dom2)
			dopatchs(patchs,zsdom)
			console.log(patchs)
		</script>
	</body>
</html>
